package com.thread_pool.thread_pool_executor;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author linjy on 2022/11/30
 */
@Slf4j(topic = "c.ExecutorServiceDemo")
public class ExecutorServiceDemo {

    @Test
    public void test1_1() throws InterruptedException, ExecutionException {

        // 创建线程池对象
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        threadPool.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("MyRunnable...run...");
            }
        });

        // 关闭线程池
        threadPool.shutdown();

    }

    @Test
    public void test1_2() throws InterruptedException, ExecutionException {

        // 创建线程池对象
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        FutureTask<String> futureTask = new FutureTask<>(new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("MyCallable...call...");
                return "success";
            }
        });
        threadPool.submit(futureTask);
        System.out.println(futureTask.get());

        // 关闭线程池
        threadPool.shutdown();

    }

    @Test
    public void test2() throws InterruptedException, ExecutionException {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        try {
            List<Future<String>> futureList = new ArrayList<>();

            List<String> list = Arrays.asList("hello", "world", "!");

            for (String str : list) {
                Callable<String> callable = () -> {
                    return str + "~";
                };
                futureList.add(executorService.submit(callable));
            }

            for (Future<String> future : futureList) {
                String result = "";
                //如果你希望按照任务完成的顺序来处理它们的结果，
                // 那么 CompletionService 可能更适合你的需求，因为它可以通过调用 take() 方法来获取下一个已完成的任务的结果。
                // 这使得你可以按照它们完成的顺序来处理任务的结果。
                // 另一方面，如果你只是想等待单个任务完成并获取它的结果，那么使用 Future 对象的 get() 方法可能更加直观和简单。


                result = future.get();
                log.info("future.get()的值：{}", result);

            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            if (!executorService.isShutdown()) {
                executorService.shutdown();
            }
        }
    }



    @Test
    public void test3() throws InterruptedException, ExecutionException {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        try {
            CompletionService<String> completionService = new ExecutorCompletionService<>(executorService);
            List<Future<String>> futureList = new ArrayList<>();

            List<String> list = Arrays.asList("hello", "world", "!");
            List<Integer> list1 = Arrays.asList(3, 2, 1);

            for (Integer s : list1) {
                Callable<String> callable = () -> {
                    TimeUnit.SECONDS.sleep(s);
                    return s + "~";
                };
                futureList.add(completionService.submit(callable));
            }

            for (Future<String> future : futureList) {
                String result = "";
                //按照任务完成的顺序返回
                /*result = completionService.take().get();
                log.info("completionService.take().get()的值：{}",result);//1~ 2~ 3~
                */

                //按照任务提交的顺序返回
                result = future.get();
                log.info("future.get()的值：{}", result);//3~ 2~ 1~

            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            if (!executorService.isShutdown()) {
                executorService.shutdown();
            }
        }
    }


}
